﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using VWise_DAO;
using System.Threading;
using System.IO;
using ThingMagic;
using System.Configuration;
using System.Media;
using VWISE_Terminal.Properties;

namespace VWISE_Terminal
{
  public partial class MainForm : Form
  {
    const int W_OK = 0; 
    const int W_FAIL = -1;


    //Agregado timer por RMB 02/01/2012
    Reader reader;

    System.Windows.Forms.Timer t;
    private object _sync = new object();
    private List<TagCl> _listTags = new List<TagCl>();

    public void AddLista(TagCl value)
    {
        lock (_sync)
        {
            _listTags.Add(value);
        }
    }
    public List<TagCl> FindLista(Predicate<TagCl> predicate)
    {
        lock (_sync)
        {
            List<TagCl> listaTemp = _listTags.FindAll(predicate);
            return listaTemp;
        }
    }

    public void DeleteLista(List<TagCl> listaTags)
    {
        lock (_sync)
        {
            foreach(var d in listaTags)
            {
                _listTags.Remove(d);
            }
        }
    }

    public TagCl FirstOrDefault()
    {
        lock (_sync)
        {
            return _listTags.FirstOrDefault();
        }
    }
    
    //FIN RMB

    bool bClose = false;

    DateTime dtActual;
    CVWise_DAO_Access pVWise_DAO_Access = new CVWise_DAO_Access();
    bool bInConsulta = false;

    public MainForm()
    {
      InitializeComponent();
    }

    private void MainForm_Load(object sender, EventArgs e)
    {
      int iPositionX, iPositionY;
      //posicionamiento del formulario principal
      this.Height = Screen.PrimaryScreen.Bounds.Height;
      this.Width = Screen.PrimaryScreen.Bounds.Width;
      this.Location = new Point(0, 0);
      this.BackColor = Color.White;

      //posicionamiento del grupo central
      iPositionY = this.Height / 2 - MainGroup.Height / 2;
      iPositionX = this.Width / 2 - MainGroup.Width / 2;
      MainGroup.Location = new Point(iPositionX,iPositionY);

      //fecha y hora actual
      dtActual = DateTime.Now;
      textHoraActual.Text = dtActual.ToString("yyyy/MM/dd HH:mm:ss");

      //imagen actual
      //picBoxFoto.Load("");

      //internal - configuracion de la consulta asincrona
      CLogProcessor.InitLog();
      pVWise_DAO_Access.Configure();
      pVWise_DAO_Access.OnVWise_DAO_Query += new CVWise_DAO_Access.VWise_DAO_QueryHandler(QueryHasFinished);

        //Crear reader
      string puertoCOM=ConfigurationSettings.AppSettings["puertoCOM"];
      reader = Reader.Create("tmr:///"+puertoCOM);

      //ingresado por RMB 02/01/2012


      try
      {
          reader.Connect();
          //rdr.Connect();
          if (Reader.Region.UNSPEC.Equals(reader.ParamGet("/reader/region/id")))
          {
              reader.ParamSet("/reader/region/id", Reader.Region.NA);
          }
          UInt16 prueba = (UInt16)reader.ParamGet("/reader/radio/readPower");
          //int max = (int)reader.ParamGet("/reader/radio/powerMax");
          //int min = (int)reader.ParamGet("/reader/radio/powerMin");
          reader.ParamSet("/reader/radio/readPower",1000);
      }
      catch (Exception excp)
      {
          MessageBox.Show(excp.Message);
      }
      finally
      {
          //reader.Destroy();

          reader.TagRead += new EventHandler<TagReadDataEventArgs>(tagRead);
          reader.StartReading();
          t = new System.Windows.Forms.Timer();
          t.Interval = 10*1000;
          t.Tick += new System.EventHandler(OnTimerEvent);
          t.Enabled=true;
          
          //timer.Enabled = true;
      }

    }

    /// <summary>
    /// Gestor de Finalizacion de Resultados
    /// </summary>
    /// <param name="pQueryObject"></param>
    /// <param name="pEventArgs"></param>
    void QueryHasFinished(object pQueryObject, CVWise_DAO_EventArgs pEventArgs)
    {
      bool bErrorReport = false;

      if (this.InvokeRequired)
      {
        CVWise_DAO_Access.VWise_DAO_QueryHandler d = new CVWise_DAO_Access.VWise_DAO_QueryHandler(QueryHasFinished);
        this.Invoke(d, pQueryObject, pEventArgs);
        return;
      }

      bInConsulta = false;
      
      switch (pEventArgs.iTypeEvent)
      {
        case CVWise_DAO_EventArgs.VWISE_DHL_NULL:
          //no se encontro
          textEstado.Text = "ERROR - NO ENCONTRADO!!";
          SetUpInformationPersona(null,DateTime.Now,0);
          bErrorReport = true;
          break;

        case CVWise_DAO_EventArgs.VWISE_DHL_PERSONAL:
          //informacion de una persona
          bErrorReport = false;
          SetUpInformationPersona(pEventArgs.pPersonal, pEventArgs.dtInOutMark, pEventArgs.iTypeMark);
          break;

        case CVWise_DAO_EventArgs.VWISE_DHL_VEHICLE:
          //informacion de un vehiculo
          bErrorReport = false;
          SetUpInforationVehicle(pEventArgs.pVehicle, pEventArgs.dtInOutMark, pEventArgs.iTypeMark);
          break;
      }

      textEstado.Visible = bErrorReport;
      if (bClose)
        this.Close();
    }

    /// <summary>
    /// Timer para actualizacion de hora en el formulario
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void timerHoraActual_Tick(object sender, EventArgs e)
    {
      DateTime dtNow = DateTime.Now;
      if (dtActual.Second != dtNow.Second)
      {
        textHoraActual.Text = dtNow.ToString("yyyy/MM/dd HH:mm:ss");
        dtActual = dtNow;
      }
    }

    /// <summary>
    /// SImulacion de entrada en dispositivo de lectura
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void MainForm_KeyUp(object sender, KeyEventArgs e)
    {
      int iPKCode;

      if (bInConsulta)
        return;


      if (e.KeyCode == Keys.Enter)
      {
          //simulamos el evento de lectura del TAG RFID

          //PKCODE, codigo recibido del RFID
          //iPKCode = new Random((int)DateTime.Now.Ticks).Next(1, 10);
          iPKCode = 12;

          //configuramos el objeto para que registre:
          pVWise_DAO_Access.iPKCodeToConsult = iPKCode;   //que codigo deseamos que busque
          pVWise_DAO_Access.bRegister = true;             //si deseamos que registre el ingreso 
          pVWise_DAO_Access.dtRegisterDateTime = DateTime.Now;    //hora actual del ingreso
          pVWise_DAO_Access.szPuertaAcceso = "TERMINAL ENTRADA";      //que puerta es

          pVWise_DAO_Access.StartQueryPersonalByIdentifier();
          textEstado.Text = "Consultando...";
          textEstado.Visible = true;
          bInConsulta = true;

      }
      //else if (e.KeyCode == Keys.Space)
      //{
      //  //simulamos el evento de lectura del TAG RFID

      //  //PKCODE, codigo recibido del RFID
      //  iPKCode = new Random((int)DateTime.Now.Ticks).Next(1, 5);
        
      //  //configuramos el objeto para que registre:
      //  pVWise_DAO_Access.iPKCodeToConsult = iPKCode;   //que codigo deseamos que busque
      //  pVWise_DAO_Access.bRegister = true;             //si deseamos que registre el ingreso 
      //  pVWise_DAO_Access.dtRegisterDateTime = DateTime.Now;    //hora actual del ingreso
      //  pVWise_DAO_Access.szPuertaAcceso = "TERMINAL DES";      //que puerta es
        
      //  pVWise_DAO_Access.StartQueryVehicleByIdentifier();
      //  textEstado.Text = "Consultando...";
      //  textEstado.Visible = true;
      //  bInConsulta = true;
      //}
    }

    /// <summary>
    /// Comprobaciones para cerrar el formulario
    /// Se debe cerrar solo si no hay consultas en curso
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
    {
      if (bInConsulta)
      {
        bClose = true;
        e.Cancel = true;
        textEstado.Text = "Cerrando...";
        textEstado.Visible = true;
      }
      else
      {
        //cerrando el formulario efecctivamente
        CLogProcessor.CloseLog();
      }
    }

    /// <summary>
    /// Mostrar en pantalla informacion del personal
    /// </summary>
    /// <param name="pPersonal"></param>
    void SetUpInformationPersona(CPersonal pPersonal, DateTime dtInput, int iEventMark)
    {
      if (pPersonal == null)
      {
        textName.Text = "NO ENCONTRADO";
        textName.ForeColor = Color.Red;
        textArea.Text = "";
        textCondicion.Text = "";
        textHora.Text = "";

        //picBoxFoto.Load("E:\\lesli03.jpg");
        //picBoxFoto.BackColor = Color.Black;
      }
      else
      {
        textName.Text = pPersonal.szPatLastName + " " + pPersonal.szMatlastName + ", " +
                      pPersonal.szFirstName;
        textName.ForeColor = (pPersonal.iCondition == 1) ? Color.Black : Color.Red;

        textArea.Text = pPersonal.szArea;
        textCondicion.Text = (pPersonal.iCondition == 1) ? "ACTIVO" : "CESADO";

        textCondicion.ForeColor = (pPersonal.iCondition == 1) ? Color.Green: Color.Red;
        
        textHora.Text = dtInput.ToString("HH:mm:ss") + " ";

        switch (iEventMark)
        {
          case CVWise_DAO_EventArgs.W_MARK_FAIL:
            textHora.Text += "(REPORTAR ERROR)";
            break;

          case CVWise_DAO_EventArgs.W_MARK_EXCEPCIONAL_INGRESO:
            textHora.Text += "(INGRESO EXCEPCIONAL)";
            break;

          case CVWise_DAO_EventArgs.W_MARK_EXCEPCIONAL_SALIDA:
            textHora.Text += "(SALIDA EXCEPCIONAL)";
            break;

          case CVWise_DAO_EventArgs.W_MARK_INGRESO:
            textHora.Text += "(INGRESO)";
            break;

          case CVWise_DAO_EventArgs.W_MARK_SALIDA:
            textHora.Text += "(SALIDA)";
            break;
        }

        
        if (File.Exists(pPersonal.szPhotoPath))
        {
          picBoxFoto.Visible = true;
          picBoxNoLogo.Visible = false;
          picBoxFoto.Load(pPersonal.szPhotoPath);
        }
        else
        {
          picBoxFoto.Visible = false;
          picBoxNoLogo.Visible = true;
        }
      }

      textTitle01.Text = "";
      textTitle02.Text = "Cargo:";
      textTitle03.Text = "Condición:";
      textTitle04.Text = "";
    }

    void SetUpInforationVehicle(CVehicle pVehicle,DateTime dtInput,int iEventMark)
    {
      if (pVehicle == null)
      {
        textName.Text = "NO ENCONTRADO";
        textName.ForeColor = Color.Red;
        textArea.Text = "";
        textCondicion.Text = "";
        textHora.Text = "";

        picBoxFoto.Visible = false;
        picBoxNoLogo.Visible = true;
        return;
      }

      textName.Text = pVehicle.szMarca + " " + pVehicle.szModelo + " " + pVehicle.szTipoVehiculo;
      textName.ForeColor = Color.Black;
      textArea.Text = pVehicle.szPlaca;
      textCondicion.Text = pVehicle.szConductor;
      textCondicion.ForeColor = Color.Black;

      textHora.Text = dtInput.ToString("HH:mm:ss") + " ";
      switch (iEventMark)
      {
        case CVWise_DAO_EventArgs.W_MARK_FAIL:
          textHora.Text += "(REPORTAR ERROR)";
          break;
      
        case CVWise_DAO_EventArgs.W_MARK_EXCEPCIONAL_INGRESO:
          textHora.Text += "(INGRESO EXCEPCIONAL)"; 
          break;

        case CVWise_DAO_EventArgs.W_MARK_EXCEPCIONAL_SALIDA:
          textHora.Text += "(SALIDA EXCEPCIONAL)";
          break;

        case CVWise_DAO_EventArgs.W_MARK_INGRESO:
          textHora.Text += "(INGRESO)"; 
          break;

        case CVWise_DAO_EventArgs.W_MARK_SALIDA:
          textHora.Text += "(SALIDA)"; 
          break;
      }

      picBoxFoto.Visible = false;
      picBoxNoLogo.Visible = true;

      textTitle01.Text = "Vehiculo:";
      textTitle02.Text = "Placa:";
      textTitle03.Text = "Conductor:";
      textTitle04.Text = "";
    }

    private void MainGroup_Enter(object sender, EventArgs e)
    {

    }

    //Metodo agregado por RMB 02/01/2012

    object objetoSinc = new object();

    void tagRead(object sender, TagReadDataEventArgs eArgs)
    {
        lock (objetoSinc) 
        {
            try
            {
                if (eArgs.TagReadData.EpcString.EndsWith("1"))
                {
                    int cadInt = int.Parse(eArgs.TagReadData.EpcString);
                    //Formato codigo+digito, si el digito es 1 es persona y deberia continuar, el resto es el codigo tag

                    cadInt = cadInt / 10;
                    string cad = cadInt.ToString();
                    int iPKCode;
                    List<TagCl> tagcl = FindLista(o => o.tagString.CompareTo(cad) == 0);
                    if (tagcl.Count == 0)
                    {
                        SoundPlayer sonido = new SoundPlayer(Resources.beep);
                        sonido.Play();
                        //SystemSounds.Exclamation.Play() ;
                        //Resources.beep
                        //System.sound;
                        //sound.Play();
                        //string ruta=
                        TagCl tagclT = new TagCl();
                        tagclT.fecha = DateTime.Now;
                        tagclT.flag = false;
                        tagclT.tagString = cad;
                        AddLista(tagclT);
                        //Tengo que ver que el epc exista
                        var bd = new DHLDataContextDataContext();


                        List<TB_M_PERSONA> listaPersonal = (from c in bd.TB_M_PERSONAs
                                                            where c.CODIGOTAG == cadInt
                                                            //&& c.N_EST_PERSONA == 1
                                                            select c).ToList();
                        if (listaPersonal.Count > 0)
                        {
                            TB_M_PERSONA persona = listaPersonal.First();
                            //PKCODE, codigo recibido del RFID
                            //iPKCode = new Random((int)DateTime.Now.Ticks).Next(1, 10);
                            iPKCode = int.Parse(persona.N_COD_PERSONA);

                            //configuramos el objeto para que registre:
                            pVWise_DAO_Access.iPKCodeToConsult = iPKCode;   //que codigo deseamos que busque
                            
                            pVWise_DAO_Access.dtRegisterDateTime = DateTime.Now;    //hora actual del ingreso
                            pVWise_DAO_Access.szPuertaAcceso = "TERMINAL";      //que puerta es

                            
                            textEstado.Text = "Consultando...";
                            //textEstado.Visible = true;
                            bInConsulta = true;
                            if (persona.N_EST_PERSONA == 0)
                            {
                                SoundPlayer sonido5 = new SoundPlayer(Resources.alarma);
                                sonido5.Play();
                                pVWise_DAO_Access.bRegister = false;             //si deseamos que registre el ingreso }
                                pVWise_DAO_Access.StartQueryPersonalByIdentifier();
                            }
                            else 
                            {
                                pVWise_DAO_Access.bRegister = true;             //si deseamos que registre el ingreso }
                                pVWise_DAO_Access.StartQueryPersonalByIdentifier();
                            }
                            
                            
                        }
                        else
                        {

                            SoundPlayer sonido2 = new SoundPlayer(Resources.alarma);
                            sonido2.Play();

                            SetTexArea("Consultando...");

                            //textArea.Text = "ERROR";
                            //configuramos el objeto para que registre:
                            
                            //textEstado.Text = "Consultando...";
                            //textEstado.Visible = true;
                            //bInConsulta = true;

                        }
                    }
                    else 
                    {
                        var bd = new DHLDataContextDataContext();

                            List<TB_M_PERSONA> listaPersonal = (from c in bd.TB_M_PERSONAs
                                                            where c.CODIGOTAG == cadInt
                                                            //&& c.N_EST_PERSONA == 1
                                                            select c).ToList();
                            if (listaPersonal.Count == 0)
                            {
                                SoundPlayer sonido3 = new SoundPlayer(Resources.alarma);
                                sonido3.Play();
                                SetTexArea("Consultando...");

                            }
                    }

                }
                else 
                {
                    SoundPlayer sonido = new SoundPlayer(Resources.alarma);
                    sonido.Play();
                    SetTexArea("Consultando...");

                }
                Thread.Sleep(500);
            }
            catch (Exception exc)
            {
                //MessageBox.Show("Error: " + exc.Message);
                SoundPlayer sonido2 = new SoundPlayer(Resources.alarma);
                sonido2.Play();

                SetTexArea("Consultando...");
            }
        }
    }

    private delegate void SetTexAreaDelegate(string cadena);

    private void SetTexArea(string texto)
      {
          if (IsHandleCreated)
          {
              if (textArea.InvokeRequired)
              {
                  textArea.Invoke(new SetTexAreaDelegate(SetTexArea), "Consultando...");
              }
              else
              {
                  textArea.Text = "ERROR";
                  textName.Text = "ERROR";
                  textHora.Text = "ERROR";
                  textCondicion.Text = "ERROR";
                  picBoxNoLogo.Visible = false;
                  picBoxFoto.Visible = false;
                  //picBoxFoto.Image = Resources.Alert;
                  //picBoxNoLogo.Image = Resources.Alert;
                  //pVWise_DAO_Access.iPKCodeToConsult = 999;   //que codigo deseamos que busque

                  //pVWise_DAO_Access.dtRegisterDateTime = DateTime.Now;    //hora actual del ingreso
                  //pVWise_DAO_Access.szPuertaAcceso = "TERMINAL";      //que puerta es
                  //pVWise_DAO_Access.bRegister = false;             //si deseamos que registre el ingreso }
                  //pVWise_DAO_Access.StartQueryPersonalByIdentifier();

                  //textEstado.Text = "Consultando...";
                  ////textEstado.Visible = true;
                  //bInConsulta = true;
                  
                  
              }
          }

       }
       

    private void OnTimerEvent(object sender, EventArgs e)
    {
        foreach(var c in _listTags)
        {
            if (DateTime.Now.Subtract(c.fecha).Minutes >= 1) 
            {
                c.flag = true;
            }
        }

        DeleteLista(_listTags.FindAll(o=>o.flag==true));
    }

    private void textTitle02_Click(object sender, EventArgs e)
    {

    }

    private void textName_Click(object sender, EventArgs e)
    {

    }

    private void textArea_Click(object sender, EventArgs e)
    {

    }

    private void picBoxNoLogo_Click(object sender, EventArgs e)
    {

    }


  }
}
